package com.sumer.psychology.photo.domain.model;

import com.sumer.psychology.common.Assert;
import com.sumer.psychology.common.domain.model.Author;
import com.sumer.psychology.common.domain.model.ConcurrencySafeEntity;

import java.util.Date;

/**
 * 相册
 * <p/>
 * User: zhenguang.zhu
 * Date: 2014/8/29
 * Time: 14:49
 */
public class Album extends ConcurrencySafeEntity {
    private AlbumId albumId;
    private String name;
    private String description;
    private Date createTime;
    private Date lastModifyTime;
    private AlbumAvailability availability;
    private Author owner;

    /**
     * 创建一个新的相册
     *
     * @param albumId     id
     * @param name        name
     * @param description desc
     */
    public Album(AlbumId albumId, String name, String description, Author owner) {
        setAlbumId(albumId);
        setName(name);
        setDescription(description);
        setCreateTime(new Date());
        setAvailability(AlbumAvailability.ACTIVE);
        setOwner(owner);

        apply(new AlbumCreatedEvent(
                albumId(),
                name(),
                description(),
                owner()));
    }

    public Album() {
    }

    /**
     * 编辑相册
     *
     * @param name name
     * @param description desc
     */
    public void changeNameAndDescription(String name, String description) {
        setName(name);
        setDescription(description);
        setLastModifyTime(new Date());

        apply(new AlbumChangedEvent(
                albumId(),
                name(),
                description()));
    }

    /**
     * 删除相册
     */
    public void delete() {
        setAvailability(AlbumAvailability.DELETED);
        setLastModifyTime(new Date());

        apply(new AlbumDeletedEvent(albumId()));
    }

    private void setAlbumId(AlbumId albumId) {
        Assert.notNull(albumId, "id不能为空");
        Assert.notEmpty(albumId.identity(), "id不能为空");

        this.albumId = albumId;
    }

    private void setName(String name) {
        Assert.notEmpty(name, "相册名称不能为空");
        Assert.length(name, 100, "相册名称不能超过50个字");

        this.name = name;
    }

    private void setDescription(String description) {
        Assert.length(description, 200, "相册描述不能超过100个字");

        this.description = description;
    }

    private void setCreateTime(Date createTime) {
        Assert.notNull(createTime, "创建日期不能为空");

        this.createTime = createTime;
    }

    private void setLastModifyTime(Date lastModifyTime) {
        this.lastModifyTime = lastModifyTime;
    }

    private void setAvailability(AlbumAvailability availability) {
        Assert.notNull(availability, "可用性不能为空");

        this.availability = availability;
    }

    private void setOwner(Author owner) {
        Assert.notNull(owner, "拥有者不能为空");
        Assert.notEmpty(owner.identity(), "拥有者不能为空");

        this.owner = owner;
    }

    public AlbumId albumId() {
        return albumId;
    }

    public String name() {
        return name;
    }

    public String description() {
        return description;
    }

    public Date createTime() {
        return createTime;
    }

    public Date lastModifyTime() {
        return lastModifyTime;
    }

    public AlbumAvailability availability() {
        return availability;
    }

    public Author owner() {
        return owner;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Album album = (Album) o;

        if (albumId != null ? !albumId.equals(album.albumId) : album.albumId != null) return false;
        if (availability != album.availability) return false;
        if (description != null ? !description.equals(album.description) : album.description != null) return false;
        if (name != null ? !name.equals(album.name) : album.name != null) return false;
        if (owner != null ? !owner.identity().equals(album.owner.identity()) : album.owner != null) return false;

        return true;
    }

    @Override
    public int hashCode() {
        int result = albumId != null ? albumId.hashCode() : 0;
        result = 31 * result + (name != null ? name.hashCode() : 0);
        result = 31 * result + (description != null ? description.hashCode() : 0);
        result = 31 * result + (availability != null ? availability.hashCode() : 0);
        result = 31 * result + (owner != null ? owner.identity().hashCode() : 0);
        return result;
    }

    @Override
    public String toString() {
        return "Album{" +
                "albumId=" + albumId +
                ", name='" + name + '\'' +
                ", description='" + description + '\'' +
                ", createTime=" + createTime +
                ", lastModifyTime=" + lastModifyTime +
                ", availability=" + availability +
                ", owner=" + owner +
                '}';
    }
}
